﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mime;
using System.Web;
using System.Web.Mvc;
using Entidades.Seguridad;
using MvcPaging;
using VistaOnlineR1._1.Models;
using Modelo.Seguridad;


namespace VistaOnlineR1._1.Controllers.Seguridad
{
    
    public class UsuariosController : BaseController
    {
         #region campos
        CatalogoUsuarios _catalogoUsuario;
        CatalogoGrupos _catalogoGrupo;
        #endregion

        #region Constructors
        public UsuariosController()
            : this(new CatalogoUsuarios(), new CatalogoGrupos())
        {
        }

        public UsuariosController(CatalogoUsuarios catalogoUsuario, CatalogoGrupos catalogoGrupo)
        {
            _catalogoUsuario = catalogoUsuario;
            _catalogoGrupo = catalogoGrupo;
        }
        #endregion

        private const int DefaultPageSize = 10;

        public ViewResultBase Search(string mombreapellido, string Grupo, bool estado, int? page)
        {

            List<Perfil> listPerfil = RecuperarPerfil();

            ViewBag.PermisoDelete = listPerfil.Any(per => per.Permiso.Nombre == "Delete");
            ViewBag.PermisoCrear = listPerfil.Any(per => per.Permiso.Nombre == "Create");
            ViewBag.PermisoEditar = listPerfil.Any(per => per.Permiso.Nombre == "Edit");

            List<Usuario> usuarios = _catalogoUsuario.ListarUsuarios(mombreapellido, estado, Grupo).ToList();            
            int currentPageIndex = page.HasValue ? page.Value - 1 : 0;


            #region  Creamos el combo de grupos
            List<SelectListItem> grup = new List<SelectListItem>();
            List<Grupo> grupos = _catalogoGrupo.ListarGrupos().ToList();
            
            foreach (var grupo in grupos)
            {
                grup.Add(new SelectListItem { Text = grupo.IdGrupo, Value = grupo.IdGrupo });
            }

            grup.Add(new SelectListItem { Text = "TODOS", Value = "TODOS" });


            ViewBag.IdGrupo = new SelectList(grup, "Value", "Text", selectedValue: Grupo);
            #endregion


            if (Request.IsAjaxRequest())
                return PartialView("Index", usuarios.OrderBy(c => c.NombreApellido).ToList().ToPagedList(currentPageIndex, DefaultPageSize));
            else
                return View("Index", usuarios.OrderBy(c => c.NombreApellido).ToList().ToPagedList(currentPageIndex, DefaultPageSize));
        }

        [Authorize(Roles = "Administracion")]
        public ActionResult Index(int? page)
        {

            List<Perfil> listPerfil = RecuperarPerfil();

            ViewBag.PermisoDelete = listPerfil.Any(per => per.Permiso.Nombre == "Delete");
            ViewBag.PermisoCrear = listPerfil.Any(per => per.Permiso.Nombre == "Create");
            ViewBag.PermisoEditar = listPerfil.Any(per => per.Permiso.Nombre == "Edit");


            #region  Creamos el combo de grupos
            List<SelectListItem> grup = new List<SelectListItem>();
            List<Grupo> grupos = _catalogoGrupo.ListarGrupos().ToList();
            
            foreach (var grupo in grupos)
            {
                grup.Add(new SelectListItem { Text = grupo.IdGrupo, Value = grupo.IdGrupo});
            }

            grup.Add(new SelectListItem { Text = "TODOS", Value = "TODOS"});


            ViewBag.IdGrupo = new SelectList(grup, "Value", "Text", selectedValue: "TODOS");
            #endregion

            List<Usuario> usuarios = _catalogoUsuario.ListarUsuarios().ToList();
            int currentPageIndex = page.HasValue ? page.Value - 1 : 0;

            return View(usuarios.OrderBy(c => c.IdUsuario).ToList().ToPagedList(currentPageIndex, DefaultPageSize));
        }

        [Authorize(Roles = "Administracion")]
        public ActionResult Create()
        {
            Usuario usuario = new Usuario();

            List<Grupo> oGrupos = _catalogoGrupo.ListarGrupos().ToList();

            var grupos = oGrupos.ToList().Select(x => new SelectListItem
            {
                Value = x.IdGrupo,
                Text = x.IdGrupo
            }).ToArray();

            var model = new UsuarioGrupos
            {
                Grupos = grupos,
                Usuario = usuario
            };

            return View(model);
        } 

       

        [HttpPost]
        [Authorize(Roles = "Administracion")]
        public ActionResult Create(UsuarioGrupos oUsuarioGrupos)
        {
            try
            {
                
                if (ModelState.IsValid)
                {
                    bool validGrupo = false;

                    foreach (var item in oUsuarioGrupos.Grupos)
                    {
                        if (item.Selected)
                        {
                            Grupo  oGrupo = new Grupo();
                            oGrupo = _catalogoGrupo.BuscarGrupo(item.Text);
                            oUsuarioGrupos.Usuario.AgregarGrupo(oGrupo);
                            validGrupo = true;
                        }
                    }

                    if (validGrupo)
                    {
                        oUsuarioGrupos.Usuario.Clave = Encriptar(oUsuarioGrupos.Usuario.Clave);


                        if (_catalogoUsuario.AgregarUsuario(oUsuarioGrupos.Usuario))
                        {
                            ModelState.AddModelError("", "El usuario se registro con exito.");
                            return RedirectToAction("Index", "Usuarios");
                        }                       
                            
                        
                        ModelState.AddModelError("", "El usuario ingresado ya pertenece al sistema.");
                        return View(oUsuarioGrupos);
                    
                    }

                    ModelState.AddModelError("", "Seleccione un grupo para el usuario.");
                    return View(oUsuarioGrupos);
                   
                }
                return View(oUsuarioGrupos);
            }
            catch
            {
                return View();
            }
        }

        [Authorize(Roles = "Administracion")]
        public ActionResult Edit(string id)
        {
            Usuario oUsuario = _catalogoUsuario.BuscarUsuario(id);

            List<Grupo> oGrupos = _catalogoGrupo.ListarGrupos().ToList();

            var usuarioGrupos = oUsuario.Grupos;

            var grupos = oGrupos.ToList().Select(x => new SelectListItem
            {
                Value = x.IdGrupo,
                Text = x.IdGrupo,
                Selected = usuarioGrupos.Any(t => t.IdGrupo == x.IdGrupo)
            }).ToArray();

            var model = new UsuarioGrupos
            {
                Grupos = grupos,
                Usuario = oUsuario
            };

            return View(model);
        }


        public ActionResult EditBis()
        {
            Usuario oUsuario = new Usuario();
            oUsuario.IdUsuario = User.Identity.Name;
            oUsuario = _catalogoUsuario.BuscarUsuario(oUsuario.IdUsuario);
            return View(oUsuario);
        }

        
        [HttpPost]
        [Authorize(Roles = "Administracion")]
        public ActionResult Edit(UsuarioGrupos oUsuarioGrupos)
        {
            try
            {
                Usuario oUsuarioNew = _catalogoUsuario.BuscarUsuario(oUsuarioGrupos.Usuario.IdUsuario);
                
                oUsuarioNew.Email = oUsuarioGrupos.Usuario.Email;
                oUsuarioNew.Estado = oUsuarioGrupos.Usuario.Estado;
                oUsuarioNew.NombreApellido = oUsuarioGrupos.Usuario.NombreApellido;

                foreach (var grupo in oUsuarioGrupos.Grupos)
                {
                    if (grupo.Selected)
                    {
                        if (!oUsuarioNew.Grupos.Any(t => t.IdGrupo == grupo.Text))
                        {
                            Grupo oGrupo = new Grupo();
                            oGrupo = _catalogoGrupo.BuscarGrupo(grupo.Text);
                            oUsuarioNew.AgregarGrupo(oGrupo);
                        }
                    }
                    else if (oUsuarioNew.Grupos.Any(t => t.IdGrupo == grupo.Text))
                    {
                        Grupo oGrupo = new Grupo();
                        oGrupo = _catalogoGrupo.BuscarGrupo(grupo.Text);
                        oUsuarioNew.EliminarGrupo(oGrupo);
                    }
                }

                _catalogoUsuario.ModificarUsuario(oUsuarioNew);

                return RedirectToAction("Index");
            }
            catch
            {
                return View(oUsuarioGrupos);
            }
        }

        [Authorize(Roles = "Administracion")]
        public ActionResult Delete(string IdUsuario)
        {
            Usuario oUsuario = _catalogoUsuario.BuscarUsuario(IdUsuario);
            return View(oUsuario);
        }

        //
        // POST: /Usuarios/Delete/5

        [HttpPost]
        [Authorize(Roles = "Administracion")]
        public ActionResult Delete(Usuario oUsuario)
        {
            try
            {
                oUsuario =_catalogoUsuario.BuscarUsuario(oUsuario.IdUsuario);
                _catalogoUsuario.EliminarUsuario(oUsuario);
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }


        public ActionResult CambiarClave()
        {
            return View();
        }

        [HttpPost]
        public ActionResult CambiarClave(Models.UsuarioModelo.CambioPasswordModel cambioPassword)
        {
            Usuario oUsuario = new Usuario();
            oUsuario.IdUsuario = User.Identity.Name;
            oUsuario = _catalogoUsuario.BuscarUsuario(oUsuario.IdUsuario);


            if (ModelState.IsValid)
            {
                // ChangePassword iniciará una excepción en lugar de
                // devolver false en determinados escenarios de error.
                bool changePasswordSucceeded = true;
                try
                {

                    string claveAtualEncrip = Encriptar(cambioPassword.OldPassword);
                    string claveNuevaEncrip = Encriptar(cambioPassword.NewPassword);

                    if (oUsuario.Clave == claveAtualEncrip)
                    {
                        oUsuario.Clave = claveNuevaEncrip;
                        _catalogoUsuario.ModificarUsuario(oUsuario);
                    }
                    else changePasswordSucceeded = false;
                    
                    
                }
                catch (Exception)
                {
                    changePasswordSucceeded = false;
                }

                if (changePasswordSucceeded)
                {
                    return RedirectToAction("ChangePasswordSuccess");
                }
                
                ModelState.AddModelError("", "La contraseña actual es incorrecta o la nueva contraseña no es válida.");
            }

            return View(cambioPassword);
        }

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }

        private string Encriptar(string valor)
        {
            System.Security.Cryptography.SHA1CryptoServiceProvider provider = new System.Security.Cryptography.SHA1CryptoServiceProvider();
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(valor);
            byte[] inArray = provider.ComputeHash(bytes);
            provider.Clear();
            return Convert.ToBase64String(inArray);
        }
    }
}
